from functools import wraps
from flask import redirect, url_for, g, abort, flash


# 无参数装饰器：用于检查是否登录的装饰器
def login_required(func):
    # `@wraps(func)`使用 `wraps` 装饰器保留被装饰函数的元数据
    # `inner包装函数，会在被装饰的视图函数之前执行
    # `*args, **kwargs`：用于接收被装饰函数的所有位置参数和关键字参数
    @wraps(func)
    def inner(*args, **kwargs):
        if not hasattr(g, "user"):
            return redirect(url_for("user.login"))
        elif not g.user.is_active:
            flash("该用户已被禁用！")
            return redirect(url_for("user.login"))
        else:
            return func(*args, **kwargs)

    return inner


# 带参数装饰器：用于针对角色做权限限制 这个有outer，是因为要接受额外参数permission
def permission_required(permission):
    def outer(func):
        @wraps(func)
        def inner(*args, **kwargs):
            if hasattr(g, "user") and g.user.has_permission(permission):
                return func(*args, **kwargs)
            else:
                return abort(403)

        return inner

    return outer
